package GUI;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;

import Control.Shape;
import Control.Shape.Category;

import com.modestmaps.InteractiveMap;
import com.modestmaps.core.Coordinate;
import com.modestmaps.geo.Location;
import com.modestmaps.providers.Microsoft;
import com.modestmaps.providers.Microsoft.AerialProvider;
import com.modestmaps.providers.Yahoo;

import processing.core.PApplet;
import processing.core.PFont;

import processing.core.*;
import Control.*;


public class Main extends PApplet {


	boolean dragged = false;
	
	
	public void setup() {
		GV.processing=this;
		GV.gu = new GradientUtils();
		GV.plotFont = loadFont("LucidaSans-48.vlw");
		GV.plotBoldFont = loadFont("LucidaSans-Demi-48.vlw");

		size(GV.width,GV.height);
		background(0);

		Shape.initShapes();
		
		//constructor loads data into memory
		GV.data=new DataClass();
		//System.out.println(GV.data.getAllUfoData().size());



		GV.scaleFactor = (float)(-1.0); 
		GV.MAX_SCALE = (float) 0.0;
		GV.mapClass = new Map();

		//init colors
		GV.colors = new int[4];		
//		GV.colors[0]= color(102,153,204); 
//		GV.colors[1]= color(153,153,51);
//		GV.colors[2]= color(204,102,119); 
//		GV.colors[3]= color(170,68,153);
		GV.colors[0]= color(51,34,136); 
		GV.colors[1]= color(68,170,153);
		GV.colors[2]= color(221,204,119); 
		GV.colors[3]= color(136,34,85);
		GV.shapeCategoryColor = true;
		GV.categoryCol = new int[4];
		GV.categoryCol[0]=GV.colors[0];
		GV.categoryCol[1]=GV.colors[1];
		GV.categoryCol[2]=GV.colors[2];
		GV.categoryCol[3]=GV.colors[3];
		GV.shapeCol = new int[Shape.Shapes.values().length];
		
		GV.shapesSelected = new ArrayList<Shape>();

		GV.shapeTextBox = new TextBox();
		GV.hoursPanel = new HoursPanel();
		GV.shapesPanel = new ShapesPanel();


		ArrayList<GregorianCalendar> dates = new ArrayList<GregorianCalendar>();

		GV.dateFirst = new GregorianCalendar(2001,0,1);
		GV.dateLast = new GregorianCalendar(2010,11,31);
		GregorianCalendar dt = new GregorianCalendar(2001,0,1);

		while(dt.before(GV.dateLast)){
			dates.add(dt);
			dt.add(Calendar.MONTH, 1);
		}

		GV.ga = new GraphsArea();

		ArrayList<GregorianCalendar> hours = new ArrayList<GregorianCalendar>();
		GV.hourStart=new GregorianCalendar(2001,0,1,0,0);
		GV.hourEnd=new GregorianCalendar(2001,0,1,23,0);
		GV.lastHourEnd = GV.hourEnd;
		GV.lastHourStart = GV.hourStart;
		GregorianCalendar dt2 = new GregorianCalendar(2001,0,1,0,0);

		while(dt2.before(GV.hourEnd)){
			hours.add(dt2);
			dt2.add(Calendar.HOUR_OF_DAY, 1);
		}
		
		GV.dateStart = GV.dateFirst;
		GV.dateStartIndex=0;
		GV.lastDateStart = GV.dateStart;
		
		GV.dateEnd = new GregorianCalendar(2002,11,1);
		GV.lastDateEnd = GV.dateEnd;
		GV.dateEndIndex = 23;
		GV.lp = new LowerPanel(dates,15,672);


		GV.hoursb = new HorizontalScrollBar(hours,true);
		GV.hoursb.width=180;
		GV.hoursb.x=GV.width-GV.hoursb.width-5;
		GV.hoursb.y=15;
		GV.hoursb.height=15;
		GV.hoursb.size = (float)1/ hours.size();


		GV.play = loadImage("Play2.png");
		GV.pause = loadImage("Pause2.png");
		GV.airportIcon = loadImage("airport3.png");
		GV.militaryBaseIcon = loadImage("militaryBase4.png");
		GV.weatherIcon = loadImage("weatherIcon.png");
		GV.meteorIcon = loadImage("meteor3.png");
		GV.ufoToDisplay = new ArrayList<UFO>();
		GV.updateUfoToDisplay();
		
		
		//updates the GV.ufoToDisplay ArrayList
		GV.createUfoToDisplay();


		// create a new map, optionally specify a provider

		GV.mapClass.map = new InteractiveMap(this,   new Microsoft.HybridProvider());
		//  map = new InteractiveMap(this, new Microsoft.RoadProvider());
		// others would be "new Microsoft.HybridProvider()" or "new Microsoft.AerialProvider()"
		// the Google ones get blocked after a few hundred tiles
		// the Yahoo ones look terrible because they're not 256px squares :)

		// set the initial location and zoom level to Chicago:
		GV.mapClass.map.setCenterZoom(new Location((float)(41.881944), (float)(-87.627778)), 5);
		// zoom 0 is the whole world, 19 is street level
		// (try some out, or use getlatlon.com to search for more)

		// set a default font for labels
		GV.mapClass.font = createFont("Helvetica", 12);
		GV.mapClass.map.MAX_IMAGES_TO_KEEP=80;
		

		// enable the mouse wheel, for zooming
		addMouseWheelListener(new java.awt.event.MouseWheelListener() { 
			public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) { 
				mouseWheel(evt.getWheelRotation());
			}
		}
				); 

		GV.cluster = new Cluster();
		
		cursor(CROSS);
		frameRate(17);

	}

	public void draw() {
		// calulcate dTime
		int t = millis();
		float dt = (float) (t - GV.timer) / (float)1000.0;
		GV.timer = t;

		GV.mapClass.draw(dt);
		GV.ga.draw();

		drawShapeTextBox();
		GV.hoursPanel.draw(dt);
		GV.shapesPanel.draw(dt);
		

		GV.lp.draw(dt);
		GV.hoursb.draw();
//		System.out.println(GV.mapClass.map.TILE_WIDTH+" "+GV.mapClass.map.TILE_HEIGHT);
//		System.out.println(GV.mapClass.map.tx+" "+
//					GV.mapClass.map.ty+" "+GV.mapClass.map.sc);

		
	}
	public void drawShapeTextBox(){
		fill(GV.textColor);
		textAlign(GV.processing.LEFT);
		textFont(GV.plotFont, 14);
		//Character Text Box
		GV.shapeTextBox.x = 0;
		GV.shapeTextBox.y = 0;
		GV.shapeTextBox.label = new String("Shapes");
		GV.shapeTextBox.draw();
	}
	// zoom in or out:
	void mouseWheel(int delta) {
		GV.mapClass.mouseWheel(delta);
	}

	public void keyReleased() {
		GV.mapClass.keyReleased();
	}
	// see if we're over any buttons, otherwise tell the map to drag
	public void mouseDragged() {
		if(!GV.shapeTextBox.scrollBar.mouseOver() && !GV.shapeTextBox.mouseOver() 
				&& !GV.hoursPanel.mouseOver() && !GV.shapesPanel.mouseOver() && !GV.lp.mouseOverArea() && !GV.hoursb.mouseOver() &&
				!GV.hoursPanel.scrollBar.mouseOver() && ! GV.ga.mouseOver() &&(GV.shapesPanel.activeCategory!=4?(!GV.shapesPanel.mouseOverArea()):true))
		{
			if(dragged)
				GV.mapClass.mouseDragged();
		}
		else dragged = false;
	}
	public void mouseClicked() {
		if(!GV.shapeTextBox.scrollBar.mouseOver() && !GV.shapeTextBox.mouseOver() && !GV.shapeTextBox.mouseOverSuggestions()
				&& !GV.hoursPanel.mouseOver() &&!GV.shapesPanel.mouseOver() && !GV.lp.mouseOverArea() && !GV.hoursb.mouseOver() &&
				!GV.hoursPanel.scrollBar.mouseOver() && ! GV.ga.mouseOver() && ! GV.hoursPanel.mouseOverArea() && 
				(GV.shapesPanel.activeCategory!=4?(!GV.shapesPanel.mouseOverArea()):true) && !GV.shapesPanel.mouseOverArea())
		{
			GV.mapClass.mouseClicked();
			GV.hoursPanel.graphButton.state=false;
			dragged = true;
		}
	}
	public void keyTyped(){
		if(GV.shapeTextBox.active)GV.shapeTextBox.keyTyped();
	}
	public void mousePressed(){
		if(GV.shapeTextBox.scrollBar.mouseOver())GV.shapeTextBox.scrollBar.mousePressed();
		if(GV.shapeTextBox.mouseOver()){
			if(!GV.shapeTextBox.active){GV.shapeTextBox.active=true;}
			else{GV.shapeTextBox.active=false;}
		}
		else if(GV.hoursPanel.scrollBar.mouseOver())GV.hoursPanel.scrollBar.mousePressed();
		else if(GV.lp.hsb.mouseOver())GV.lp.hsb.mousePressed();
		else if(GV.hoursb.mouseOver())GV.hoursb.mousePressed();
		else if((!GV.shapeTextBox.mouseOverSuggestions() || !GV.shapeTextBox.active))
		{	
			GV.shapeTextBox.active=false;
			dragged = true;
		}

	}
	public void mouseReleased(){
		GV.shapeTextBox.scrollBar.mouseReleased();
		GV.hoursPanel.scrollBar.mouseReleased();
		GV.lp.hsb.mouseReleased();
		GV.hoursb.mouseReleased();
	}
	public static void main(String [] args){
		PApplet.main(new String[] { "--present", "GUI.Main" });
	}

}


